from quant_researcher.quant.project_tool.time_tool import get_today, date_shifter, str_to_timestamp
import time
import requests
import json
import pandas as pd
import datetime


def get_total_marketcap_amount_via_http(exclude_btc=False, **kwargs):
    """
    爬取coinmarketcap网站上的所有币的市值，与总的交易金额

    :param exclude_btc: 是否包含BTC， 默认是包含的
    :param kwargs: 关键字参数
        - str period: '1Y', '2Y', '5Y', 'ALL'
    :return:
    """
    period = kwargs.pop('period', 'ALL')
    try:
        today = get_today(marker='with_n_dash')
        end = int(time.time())
        date_pair_list = []
        if period != 'ALL':
            years = int(period[0])  # 获取近多少年数据
            start_date = date_shifter(before=today, step='years', how_many=-years)
            date_pair_list.append([end, start_date])
        else:
            start_date = date_shifter(before=today, step='years', how_many=-5)  # 默认取近5年的数据，注意数据取太长会报错, start_date的最小取值2013-04-28
            while start_date > '2013-04-28':
                date_pair_list.append([end, start_date])
                end = str_to_timestamp(start_date)
                start_date = date_shifter(before=start_date, step='years', how_many=-5)
            date_pair_list.append([end, '2013-04-28'])

        header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'}

        df_list = []
        for date_pair in date_pair_list:
            if exclude_btc:
                # url = f'https://web-api.coinmarketcap.com/v1.1/global-metrics/quotes/historical?format=chart_altcoin&interval=1d&time_end={date_pair[0]}&time_start={date_pair[1]}'  # 读取的数据有问题
                url = f'https://api.coinmarketcap.com/data-api/v3/global-metrics/quotes/historical?format=chart_altcoin&interval=1d&timeEnd={date_pair[0]}&timeStart={date_pair[1]}'
            else:
                # url = f'https://web-api.coinmarketcap.com/v1.1/global-metrics/quotes/historical?format=chart&interval=1d&time_end={date_pair[0]}&time_start={date_pair[1]}'  # 读取的数据有问题
                url = f'https://api.coinmarketcap.com/data-api/v3/global-metrics/quotes/historical?format=chart&interval=1d&timeEnd={date_pair[0]}&timeStart={date_pair[1]}'
            a = requests.get(url, headers=header, timeout=30)
            res = json.loads(a.text)
            if 'data' not in res.keys():
                print(f'数据无法获取, 提示{res["status"]["error_message"]}')
                return None
            elif a.status_code == 200 and len(res['data']) == 0:
                print(f'数据为空无法获取')
                return None
            res_list = []
            for item in res['data']['quotes']:
                item_quote = item.pop('quote')
                item.update(item_quote[0])
                res_list.append(item)
            df = pd.DataFrame(res_list)

            if not df.empty:
                df = df[['timestamp', 'totalMarketCap', 'totalVolume24H', 'totalVolume24HReported', 'btcDominance']]
                df.rename(columns={'totalMarketCap': 'market_cap', 'totalVolume24H': 'amount', 'totalVolume24HReported': 'amount_reported'}, inplace=True)
                df['timestamp'] = pd.to_datetime(df['timestamp'])
                df['timestamp'] = df['timestamp'].apply(lambda x: x - datetime.timedelta(seconds=1))  # 时间记录的为0点，但是其实是统计的前一天的数据； 统一减去1秒，调整到昨天
                df['end_date'] = df['timestamp'].dt.strftime('%Y-%m-%d')
                df['datetime'] = df['timestamp'].dt.strftime('%Y-%m-%d %H:%M:%S')
                df.drop(['timestamp'], axis=1, inplace=True)
                df.set_index('end_date', inplace=True)
                df.sort_values(by=['end_date'], inplace=True)
                df_list.append(df)

        all_df = pd.concat(df_list, axis=0)
        if '2022-05-12' not in all_df.index:  #
            all_df.loc['2022-05-12', 'market_cap'] = 1225934966070.32
            all_df.loc['2022-05-12', 'amount'] = 197051431678.51
            all_df.loc['2022-05-12', 'amount_reported'] = 500887098639.66
            all_df.loc['2022-05-12', 'btcDominance'] = 44.46
            all_df.loc['2022-05-12', 'datetime'] = '2022-05-12 23:59:59'
        if '2023-01-04' not in all_df.index:  #
            all_df.loc['2023-01-04', 'market_cap'] = 820040249248.98
            all_df.loc['2023-01-04', 'amount'] = 32579218979.2
            all_df.loc['2023-01-04', 'amount_reported'] = 126276002454.92
            all_df.loc['2023-01-04', 'btcDominance'] = 39.5279
            all_df.loc['2023-01-04', 'datetime'] = '2023-01-04 23:59:59'
        # 2021-02-26， 2022-02-23数据异常，需要手动修改
        all_df.loc['2021-02-26', 'amount'] = 154578653169.09
        all_df.loc['2021-02-26', 'amount_reported'] = 399981671502.26
        all_df.loc['2022-02-23', 'amount'] = 82904025618.43

        all_df.sort_index(inplace=True)
        all_df = all_df[~all_df.index.duplicated(keep='first')]  # 去重
        all_df = all_df[all_df.index != today]  # 今天的数据不完整，剔除掉
        print(f'coinmarketcap网站上的所有币的市值，与总的交易金额获取成功')

    except Exception as err:
        raise err

    return all_df


if __name__ == "__main__":
    get_total_marketcap_amount_via_http(exclude_btc=False)